home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / oledocob.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  24.6 KB  |  933 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef _DEBUG
  14. #undef THIS_FILE
  15. static char BASED_CODE THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. #define new DEBUG_NEW
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CDocObjectServer
  22.  
  23. IMPLEMENT_DYNAMIC(CDocObjectServer, CCmdTarget)
  24.  
  25. BEGIN_MESSAGE_MAP(CDocObjectServer, CCmdTarget)
  26.     //{{AFX_MSG_MAP(CDocObjectServer)
  27.         // NOTE - the ClassWizard will add and remove mapping macros here.
  28.     //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30.  
  31. BEGIN_INTERFACE_MAP(CDocObjectServer, CCmdTarget)
  32.     INTERFACE_PART(CDocObjectServer, IID_IOleObject, OleObject)
  33.     INTERFACE_PART(CDocObjectServer, IID_IOleDocument, OleDocument)
  34.     INTERFACE_PART(CDocObjectServer, IID_IOleDocumentView, OleDocumentView)
  35.     INTERFACE_PART(CDocObjectServer, IID_IOleCommandTarget, OleCommandTarget)
  36.     INTERFACE_PART(CDocObjectServer, IID_IPrint, Print)
  37. END_INTERFACE_MAP()
  38.  
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CDocObjectServer implementation
  42.  
  43. CDocObjectServer::CDocObjectServer(COleServerDoc* pDoc,
  44.     LPOLEDOCUMENTSITE pDocSite /* = NULL */)
  45. {
  46.     // Initialize DocObject data
  47.     m_pDocSite  = pDocSite;
  48.     m_pViewSite = NULL;
  49.  
  50.     m_pOwner = pDoc;
  51.     ASSERT(m_pOwner != NULL);
  52.  
  53.     m_nFirstPage = 1;
  54.  
  55.     // All Binder-Compatible documents use Compound Files as their
  56.     // storage mechanism
  57.     m_pOwner->EnableCompoundFile(TRUE);
  58.  
  59.     m_nFirstPage = -1;
  60. }
  61.  
  62. CDocObjectServer::~CDocObjectServer()
  63. {
  64.     ReleaseDocSite();
  65. }
  66.  
  67. void CDocObjectServer::ReleaseDocSite()
  68. {
  69.     if (m_pDocSite != NULL)
  70.     {
  71.         m_pDocSite->Release();
  72.         m_pDocSite = NULL;
  73.     }
  74. }
  75.  
  76. void CDocObjectServer::SetDocSite(LPOLEDOCUMENTSITE pNewSite)
  77. {
  78.     ReleaseDocSite();
  79.     m_pDocSite = pNewSite;
  80. }
  81.  
  82. void CDocObjectServer::OnCloseDocument()
  83. {
  84.     // Clean up pointer to document site, if any
  85.     ReleaseDocSite();
  86.     m_pOwner->OnCloseDocument();
  87. }
  88.  
  89. void CDocObjectServer::ActivateDocObject()
  90. {
  91.     ASSERT(m_pOwner != NULL);
  92.     if (m_pOwner->IsDocObject())
  93.     {
  94.         ASSERT(m_pDocSite != NULL);
  95.         m_pDocSite->ActivateMe(NULL);
  96.     }
  97. }
  98.  
  99. STDMETHODIMP CDocObjectServer::OnExecOleCmd(
  100.    const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  101.    VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
  102. {
  103.     ASSERT(m_pOwner != NULL);
  104.     if (m_pOwner == NULL)
  105.         return E_NOTIMPL;
  106.     else
  107.         return m_pOwner->OnExecOleCmd(pguidCmdGroup, nCmdID,
  108.             nCmdExecOpt, pvarargIn, pvarargOut);
  109. }
  110.  
  111. COleDocIPFrameWnd* CDocObjectServer::GetControllingFrame() const
  112. {
  113.     COleDocIPFrameWnd* pFrame = NULL;
  114.     POSITION pos = m_pOwner->GetFirstViewPosition();
  115.     if (pos != NULL)
  116.     {
  117.         CView* pView = m_pOwner->GetNextView(pos);
  118.         if (pView != NULL)
  119.         {
  120.             CWnd* pParent = pView->GetParent();
  121.             pFrame = DYNAMIC_DOWNCAST(COleDocIPFrameWnd, pParent);
  122.         }
  123.     }
  124.  
  125. #ifdef _DEBUG
  126.     // This TRACE will trip if you've not converted your application to
  127.     // use a COleDocIPFrameWnd, or if you've incorrectly hooked up
  128.     // DocObject support in your application.
  129.  
  130.     if (pFrame == NULL)
  131.         TRACE0("Error: An appropriate DocObject frame could not be found.\n");
  132. #endif
  133.  
  134.     return pFrame;
  135. }
  136.  
  137. BOOL CDocObjectServer::DoPreparePrinting(CView* pView, CPrintInfo* printInfo)
  138. {
  139.     return pView->OnPreparePrinting(printInfo);
  140. }
  141.  
  142. void CDocObjectServer::DoPrepareDC(CView* pView, CDC* pdcPrint,
  143.     CPrintInfo* pprintInfo)
  144. {
  145.     pView->OnPrepareDC(pdcPrint, pprintInfo);
  146. }
  147.  
  148. void CDocObjectServer::DoPrint(CView* pView, CDC* pdcPrint,
  149.     CPrintInfo* pprintInfo)
  150. {
  151.     pView->OnPrint(pdcPrint, pprintInfo);
  152. }
  153.  
  154. void CDocObjectServer::DoBeginPrinting(CView* pView,
  155.     CDC* pDC, CPrintInfo* pprintInfo)
  156. {
  157.     pView->OnBeginPrinting(pDC, pprintInfo);
  158. }
  159.  
  160. void CDocObjectServer::DoEndPrinting(CView* pView,
  161.     CDC* pDC, CPrintInfo* pprintInfo)
  162. {
  163.     pView->OnEndPrinting(pDC, pprintInfo);
  164. }
  165.  
  166.  
  167. /////////////////////////////////////////////////////////////////////////////
  168. // IPrint interface
  169.  
  170. extern BOOL CALLBACK _AfxAbortProc(HDC, int);   // from VIEWPRNT.CPP
  171.  
  172. STDMETHODIMP_(ULONG) CDocObjectServer::XPrint::AddRef()
  173. {
  174.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  175.     return pThis->m_pOwner->ExternalAddRef();
  176. }
  177.  
  178. STDMETHODIMP_(ULONG) CDocObjectServer::XPrint::Release()
  179. {
  180.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  181.     return pThis->m_pOwner->ExternalRelease();
  182. }
  183.  
  184. STDMETHODIMP CDocObjectServer::XPrint::QueryInterface(
  185.     REFIID iid, LPVOID* ppvObj)
  186. {
  187.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  188.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  189. }
  190.  
  191. STDMETHODIMP CDocObjectServer::XPrint::SetInitialPageNum(
  192.    LONG nFirstPage)
  193. {
  194.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  195.     ASSERT_VALID(pThis);
  196.     pThis->m_nFirstPage = nFirstPage;
  197.  
  198.     return S_OK;
  199. }
  200.  
  201. STDMETHODIMP CDocObjectServer::XPrint::GetPageInfo(
  202.    LPLONG pnFirstPage, LPLONG pcPages)
  203. {
  204.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  205.     ASSERT_VALID(pThis);
  206.  
  207.     // find the view we need to print
  208.  
  209.     CView* pView = NULL;
  210.     POSITION pos = pThis->m_pOwner->GetFirstViewPosition();
  211.     if (pos != NULL)
  212.         pView = pThis->m_pOwner->GetNextView(pos);
  213.  
  214.     if (pView == NULL)
  215.         return E_UNEXPECTED;
  216.  
  217.     // tell the view that we're not actually printing
  218.     // and just need to measure the print job
  219.  
  220.     CPrintInfo printInfo;
  221.     printInfo.m_bDocObject = TRUE;
  222.     printInfo.m_dwFlags = PRINTFLAG_DONTACTUALLYPRINT;
  223.  
  224.     // ask the view about it
  225.  
  226.     if (!pThis->DoPreparePrinting(pView, &printInfo))
  227.         return E_UNEXPECTED;
  228.  
  229.     // pnFirstPage and pcPages are allowed to be NULL
  230.     // if NULL, don't return results to caller
  231.  
  232.     if (pnFirstPage != NULL)
  233.     {
  234.         if (pThis->m_nFirstPage == -1)
  235.             *pnFirstPage = printInfo.GetMinPage();
  236.         else
  237.             *pnFirstPage = pThis->m_nFirstPage;
  238.     }
  239.  
  240.     if (pcPages != NULL)
  241.     {
  242.         if (printInfo.GetToPage() == 0xFFFF)
  243.             *pcPages = 0xFFFF;
  244.         else
  245.             *pcPages = printInfo.GetToPage() - printInfo.GetFromPage() +1;
  246.     }
  247.  
  248.     return S_OK;
  249. }
  250.  
  251. STDMETHODIMP CDocObjectServer::XPrint::Print(
  252.    DWORD grfFlags, DVTARGETDEVICE** ppTD, PAGESET** ppPageSet,
  253.    LPSTGMEDIUM pstgmOptions, LPCONTINUECALLBACK pCallback, LONG nFirstPage,
  254.    LPLONG pcPagesPrinted, LPLONG pnLastPage)
  255. {
  256.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  257.     ASSERT_VALID(pThis);
  258.     UNUSED_ALWAYS(pstgmOptions);
  259.     UNUSED_ALWAYS(pnLastPage);
  260.  
  261.     // try to get out of this without doing any work
  262.  
  263.     if (pcPagesPrinted == NULL || ppTD == NULL || ppPageSet == NULL)
  264.         return E_POINTER;
  265.  
  266.     if (*ppTD == NULL)
  267.         return E_INVALIDARG;
  268.  
  269.     // get initialized
  270.  
  271.     DVTARGETDEVICE* ptd = *ppTD;
  272.     pThis->m_nFirstPage = nFirstPage;
  273.     *pcPagesPrinted = 0;
  274.  
  275.     // find the view we need to print
  276.  
  277.     CView* pView = NULL;
  278.     POSITION pos = pThis->m_pOwner->GetFirstViewPosition();
  279.     if (pos != NULL)
  280.         pView = pThis->m_pOwner->GetNextView(pos);
  281.  
  282.     if (pView == NULL)
  283.         return E_UNEXPECTED;
  284.  
  285.     // get default print info
  286.     CPrintInfo printInfo;
  287.     ASSERT(printInfo.m_pPD != NULL);    // must be set
  288.     printInfo.m_bDocObject = TRUE;
  289.     printInfo.m_dwFlags = grfFlags;
  290.     printInfo.m_nOffsetPage = nFirstPage;
  291.  
  292.     printInfo.m_pPD->m_pd.hDC = _AfxOleCreateDC(*ppTD);
  293.     if (printInfo.m_pPD->m_pd.hDC == NULL)
  294.     {
  295.         if (grfFlags & PRINTFLAG_MAYBOTHERUSER)
  296.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  297.         return E_UNEXPECTED;
  298.     }
  299.  
  300.     if (pThis->DoPreparePrinting(pView, &printInfo))
  301.     {
  302.         // hDC must be set (did you remember to call DoPreparePrinting?)
  303.         ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
  304.  
  305.         // set file to print to if print-to-file selected
  306.         CString strOutput;
  307.         if (grfFlags & PRINTFLAG_PRINTTOFILE)
  308.             strOutput = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  309.  
  310.         // if we were to prompt, we'll need to copy info from the
  311.         // user back to the client
  312.  
  313.         if (grfFlags & PRINTFLAG_PROMPTUSER)
  314.         {
  315.             if (grfFlags & PRINTFLAG_USERMAYCHANGEPRINTER)
  316.             {
  317.                 LPDEVNAMES lpDevNames =
  318.                     (LPDEVNAMES) GlobalLock(printInfo.m_pPD->m_pd.hDevNames);
  319.                 LPDEVMODE lpDevMode =
  320.                     (LPDEVMODE) GlobalLock(printInfo.m_pPD->m_pd.hDevMode);
  321.  
  322.                 if (lpDevNames == NULL || lpDevMode == NULL)
  323.                     *ppTD = NULL;
  324.                 else
  325.                     *ppTD = _AfxOleCreateTargetDevice(lpDevNames, lpDevMode);
  326.  
  327.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevNames);
  328.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevMode);
  329.             }
  330.  
  331.             // MFC page ranges (for now) only have one PAGERANGE
  332.  
  333.             LPMALLOC pMalloc = NULL;
  334.  
  335.             // if the caller didn't supply a buffer, allocate one
  336.             // else, make sure the buffer is big enough
  337.  
  338.             if (*ppPageSet == NULL)
  339.             {
  340.                 HRESULT hrCopying = CoGetMalloc(1, &pMalloc);
  341.                 if (FAILED(hrCopying))
  342.                     return hrCopying;
  343.  
  344.                 *ppPageSet =
  345.                     (PAGESET*) pMalloc->Alloc(sizeof(PAGESET) + sizeof(PAGERANGE));
  346.             }
  347.             else
  348.             {
  349.                 if ((*ppPageSet)->cPageRange < 1 ||
  350.                     (*ppPageSet)->cbStruct != sizeof(PAGESET))
  351.                 {
  352.                     return E_INVALIDARG;
  353.                 }
  354.             }
  355.  
  356.             if (*ppPageSet != NULL)
  357.             {
  358.                 (*ppPageSet)->cbStruct = sizeof(PAGESET);
  359.                 (*ppPageSet)->fOddPages = TRUE;
  360.                 (*ppPageSet)->fEvenPages = TRUE;
  361.                 (*ppPageSet)->cPageRange = 1;
  362.  
  363.                 (*ppPageSet)->rgPages[0].nFromPage = printInfo.GetFromPage();
  364.                 (*ppPageSet)->rgPages[0].nToPage = printInfo.GetToPage();
  365.             }
  366.  
  367.             RELEASE(pMalloc);
  368.  
  369.             if (*ppTD == NULL || *ppPageSet == NULL)
  370.                 return E_UNEXPECTED;
  371.         }
  372.  
  373.         // if the client didn't really want to print,
  374.         // we've collected all the information we need
  375.         if (grfFlags & PRINTFLAG_DONTACTUALLYPRINT)
  376.             return S_OK;
  377.  
  378.         // set up document info and start the document printing process
  379.         CString strTitle;
  380.         CDocument* pDoc = pThis->m_pOwner;
  381.         if (pDoc != NULL)
  382.             strTitle = pDoc->GetTitle();
  383.         else
  384.             pView->GetParentFrame()->GetWindowText(strTitle);
  385.  
  386.         if (strTitle.GetLength() > 31)
  387.             strTitle.ReleaseBuffer(31);
  388.  
  389.         DOCINFO docInfo;
  390.         memset(&docInfo, 0, sizeof(DOCINFO));
  391.         docInfo.cbSize = sizeof(DOCINFO);
  392.         docInfo.lpszDocName = strTitle;
  393.         CString strPortName;
  394.         int nFormatID;
  395.         if (strOutput.IsEmpty())
  396.         {
  397.             docInfo.lpszOutput = NULL;
  398.             strPortName = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  399.             nFormatID = AFX_IDS_PRINTONPORT;
  400.         }
  401.         else
  402.         {
  403.             docInfo.lpszOutput = strOutput;
  404.             AfxGetFileTitle(strOutput,
  405.                 strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
  406.             nFormatID = AFX_IDS_PRINTTOFILE;
  407.         }
  408.  
  409.         // setup the printing DC
  410.         CDC dcPrint;
  411.         dcPrint.Attach(printInfo.m_pPD->m_pd.hDC);  // attach printer dc
  412.         dcPrint.m_bPrinting = TRUE;
  413.         pThis->DoBeginPrinting(pView, &dcPrint, &printInfo);
  414.         dcPrint.SetAbortProc(_AfxAbortProc);
  415.  
  416.         // disable main window while printing & init printing status dialog
  417.         AfxGetMainWnd()->EnableWindow(FALSE);
  418.  
  419.         CString strTemp;
  420.  
  421.         // start document printing process
  422.         if (dcPrint.StartDoc(&docInfo) == SP_ERROR)
  423.         {
  424.             // enable main window before proceeding
  425.             AfxGetMainWnd()->EnableWindow(TRUE);
  426.  
  427.             // cleanup and show error message
  428.             pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  429.             dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  430.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  431.             return E_UNEXPECTED;
  432.         }
  433.  
  434.         // Guarantee values are in the valid range
  435.         UINT nEndPage = printInfo.GetToPage();
  436.         UINT nStartPage = printInfo.GetFromPage();
  437.  
  438.         if (nEndPage < printInfo.GetMinPage())
  439.             nEndPage = printInfo.GetMinPage();
  440.         if (nEndPage > printInfo.GetMaxPage())
  441.             nEndPage = printInfo.GetMaxPage();
  442.  
  443.         if (nStartPage < printInfo.GetMinPage())
  444.             nStartPage = printInfo.GetMinPage();
  445.         if (nStartPage > printInfo.GetMaxPage())
  446.             nStartPage = printInfo.GetMaxPage();
  447.  
  448.         int nStep = (nEndPage >= nStartPage) ? 1 : -1;
  449.         nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep;
  450.  
  451.         VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));
  452.  
  453.         // begin page printing loop
  454.         BOOL bError = FALSE;
  455.         HRESULT hrContinue = S_OK;
  456.  
  457.         for (printInfo.m_nCurPage = nStartPage;
  458.             printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep)
  459.         {
  460.             if (printInfo.m_nCurPage % 2 == 1 && !(*ppPageSet)->fOddPages)
  461.                 continue;
  462.             if (printInfo.m_nCurPage % 2 == 0 && !(*ppPageSet)->fEvenPages)
  463.                 continue;
  464.  
  465.             pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  466.  
  467.             // check for end of print
  468.             if (!printInfo.m_bContinuePrinting)
  469.                 break;
  470.  
  471.             // set up drawing rect to entire page (in logical coordinates)
  472.             printInfo.m_rectDraw.SetRect(0, 0,
  473.                 dcPrint.GetDeviceCaps(HORZRES),
  474.                 dcPrint.GetDeviceCaps(VERTRES));
  475.             dcPrint.DPtoLP(&printInfo.m_rectDraw);
  476.  
  477.             // attempt to start the current page
  478.             if (dcPrint.StartPage() < 0)
  479.             {
  480.                 bError = TRUE;
  481.                 break;
  482.             }
  483.  
  484.             // must call OnPrepareDC on newer versions of Windows because
  485.             // StartPage now resets the device attributes.
  486.             if (afxData.bMarked4)
  487.                 pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  488.  
  489.             ASSERT(printInfo.m_bContinuePrinting);
  490.  
  491.             hrContinue = S_OK;
  492.  
  493.             if (pCallback != NULL)
  494.             {
  495.                 hrContinue = pCallback->FContinuePrinting(printInfo.m_nCurPage,
  496.                     printInfo.m_nCurPage + printInfo.m_nOffsetPage, NULL);
  497.             }
  498.  
  499.             // page successfully started, so now render the page
  500.             pThis->DoPrint(pView, &dcPrint, &printInfo);
  501.             if (dcPrint.EndPage() < 0 ||
  502.                 !_AfxAbortProc(dcPrint.m_hDC, 0) ||
  503.                 hrContinue != S_OK)
  504.             {
  505.                 bError = TRUE;
  506.                 break;
  507.             }
  508.  
  509.             // increment count
  510.             (*pcPagesPrinted)++;
  511.         }
  512.  
  513.         // cleanup document printing process
  514.         if (!bError)
  515.             dcPrint.EndDoc();
  516.         else
  517.             dcPrint.AbortDoc();
  518.  
  519.         AfxGetMainWnd()->EnableWindow();    // enable main window
  520.  
  521.         // clean up after printing
  522.         pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  523.         dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  524.  
  525.         if (bError)
  526.         {
  527.             if (hrContinue != S_OK)
  528.                 return PRINT_E_CANCELLED;
  529.             else
  530.                 return E_UNEXPECTED;
  531.         }
  532.     }
  533.  
  534.     return S_OK;
  535. }
  536.  
  537. /////////////////////////////////////////////////////////////////////////////
  538. // IOleDocument interface
  539.  
  540. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::AddRef()
  541. {
  542.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  543.     return pThis->m_pOwner->ExternalAddRef();
  544. }
  545.  
  546. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::Release()
  547. {
  548.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  549.     return pThis->m_pOwner->ExternalRelease();
  550. }
  551.  
  552. STDMETHODIMP CDocObjectServer::XOleDocument::QueryInterface(
  553.     REFIID iid, LPVOID* ppvObj)
  554. {
  555.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  556.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  557. }
  558.  
  559. STDMETHODIMP CDocObjectServer::XOleDocument::CreateView(
  560.    LPOLEINPLACESITE pipsite, LPSTREAM pstm,
  561.    DWORD dwReserved, LPOLEDOCUMENTVIEW* ppview)
  562. {
  563.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  564.    ASSERT_VALID(pThis);
  565.  
  566.    *ppview = NULL;
  567.  
  568.    HRESULT hr = E_FAIL;
  569.  
  570.    if (dwReserved == 0 && pThis->m_pDocSite != NULL)
  571.    {
  572.       // We only support a single view...so if view site is already
  573.       // set, fail.
  574.       if (pThis->m_pViewSite == NULL)
  575.       {
  576.          LPOLEDOCUMENTVIEW pView =
  577.             (LPOLEDOCUMENTVIEW)pThis->GetInterface(&IID_IOleDocumentView);
  578.          ASSERT(pView != NULL);
  579.  
  580.          // Set the site for the view
  581.          hr = pView->SetInPlaceSite(pipsite);
  582.          if (hr == NOERROR)
  583.          {
  584.             // Return the IOleDocumentView pointer
  585.             pView->AddRef();
  586.             *ppview = pView;
  587.          }
  588.  
  589.          // If a saved view state is provided, restore the view state
  590.          if (pstm)
  591.             hr = pView->ApplyViewState(pstm);
  592.       }
  593.       else
  594.          TRACE0("CDocObjectServer::XOleDocument::CreateView view already exists!\n");
  595.    }
  596.  
  597.    return hr;
  598. }
  599.  
  600. STDMETHODIMP CDocObjectServer::XOleDocument::GetDocMiscStatus(
  601.    LPDWORD pdwStatus)
  602. {
  603.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  604.    ASSERT_VALID(pThis);
  605.    ASSERT(pdwStatus != NULL);
  606.  
  607.    // Our implementation of DocObjects can't create multiple views,
  608.    // does not support complex rectangles, supports open editing,
  609.    // and supports read/write to a file. Thus DOCMISC == 0.
  610.    *pdwStatus = 0;
  611.  
  612.    return NOERROR;
  613. }
  614.  
  615. STDMETHODIMP CDocObjectServer::XOleDocument::EnumViews(
  616.    LPENUMOLEDOCUMENTVIEWS* ppEnumView, LPOLEDOCUMENTVIEW* ppView)
  617. {
  618.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  619.    ASSERT_VALID(pThis);
  620.    ASSERT(ppEnumView != NULL);
  621.    ASSERT(ppView != NULL);
  622.  
  623.    // We only support a single view
  624.    *ppEnumView = NULL;
  625.    HRESULT hr = QueryInterface(IID_IOleDocumentView, (LPVOID*)ppView);
  626.    return hr;
  627. }
  628.  
  629. /////////////////////////////////////////////////////////////////////////////
  630. // IOleObject interface
  631.  
  632. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::AddRef()
  633. {
  634.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  635.     return pThis->m_pOwner->ExternalAddRef();
  636. }
  637.  
  638. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::Release()
  639. {
  640.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  641.     return pThis->m_pOwner->ExternalRelease();
  642. }
  643.  
  644. STDMETHODIMP CDocObjectServer::XOleObject::QueryInterface(
  645.     REFIID iid, LPVOID* ppvObj)
  646. {
  647.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  648.     return pThis->m_pOwner->ExternalQueryInterface(&iid, ppvObj);
  649. }
  650.  
  651. STDMETHODIMP CDocObjectServer::XOleObject::SetClientSite(
  652.     LPOLECLIENTSITE pClientSite)
  653. {
  654.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  655.     ASSERT_VALID(pThis);
  656.     HRESULT hr = NOERROR;
  657.  
  658.     // Perform normal SetClientSite processing.
  659.     hr = pThis->m_pOwner->m_xOleObject.SetClientSite(pClientSite);
  660.     if (hr != S_OK)
  661.         return hr;
  662.  
  663.     // If we currently have a document site pointer,
  664.     // release it.
  665.  
  666.     pThis->ReleaseDocSite();
  667.  
  668.     // Check to see whether this object should act
  669.     // as a document object by querying for
  670.     // IOleDocumentSite.
  671.     if (pClientSite != NULL)
  672.         hr = pClientSite->QueryInterface(IID_IOleDocumentSite,
  673.             (LPVOID*)&pThis->m_pDocSite);
  674.     return hr;
  675. }
  676.  
  677. STDMETHODIMP CDocObjectServer::XOleObject::GetClientSite(
  678.     LPOLECLIENTSITE* ppClientSite)
  679. {
  680.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  681.     ASSERT_VALID(pThis);
  682.     return pThis->m_pOwner->m_xOleObject.GetClientSite(ppClientSite);
  683. }
  684.  
  685. STDMETHODIMP CDocObjectServer::XOleObject::SetHostNames(
  686.     LPCOLESTR lpszContainerApp, LPCOLESTR lpszContainerObj)
  687. {
  688.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  689.     ASSERT_VALID(pThis);
  690.     return pThis->m_pOwner->m_xOleObject.SetHostNames(lpszContainerApp,
  691.                                            lpszContainerObj);
  692. }
  693.  
  694. STDMETHODIMP CDocObjectServer::XOleObject::Close(DWORD dwSaveOption)
  695. {
  696.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  697.     ASSERT_VALID(pThis);
  698.     return pThis->m_pOwner->m_xOleObject.Close(dwSaveOption);
  699. }
  700.  
  701. STDMETHODIMP CDocObjectServer::XOleObject::SetMoniker(
  702.     DWORD dwWhichMoniker, LPMONIKER pmk)
  703. {
  704.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  705.     ASSERT_VALID(pThis);
  706.     return pThis->m_pOwner->m_xOleObject.SetMoniker(dwWhichMoniker, pmk);
  707. }
  708.  
  709. STDMETHODIMP CDocObjectServer::XOleObject::GetMoniker(
  710.     DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
  711. {
  712.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  713.     ASSERT_VALID(pThis);
  714.     return pThis->m_pOwner->m_xOleObject.GetMoniker(dwAssign, dwWhichMoniker,
  715.                                          ppMoniker);
  716. }
  717.  
  718. STDMETHODIMP CDocObjectServer::XOleObject::InitFromData(
  719.     LPDATAOBJECT pDataObject, BOOL bCreation, DWORD dwReserved)
  720. {
  721.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  722.     ASSERT_VALID(pThis);
  723.     return pThis->m_pOwner->m_xOleObject.InitFromData(pDataObject, bCreation,
  724.                                            dwReserved);
  725. }
  726.  
  727. STDMETHODIMP CDocObjectServer::XOleObject::GetClipboardData(
  728.     DWORD dwReserved, LPDATAOBJECT* ppDataObject)
  729. {
  730.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  731.     ASSERT_VALID(pThis);
  732.     return pThis->m_pOwner->m_xOleObject.GetClipboardData(dwReserved,
  733.                                                ppDataObject);
  734.  
  735. }
  736.  
  737. STDMETHODIMP CDocObjectServer::XOleObject::DoVerb(
  738.     LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex,
  739.     HWND hwndParent, LPCRECT lpPosRect)
  740. {
  741.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  742.     ASSERT_VALID(pThis);
  743.     return pThis->m_pOwner->m_xOleObject.DoVerb(iVerb, lpmsg,
  744.         pActiveSite, lindex, hwndParent, lpPosRect);
  745. }
  746.  
  747. STDMETHODIMP CDocObjectServer::XOleObject::EnumVerbs(
  748.     IEnumOLEVERB** ppenumOleVerb)
  749. {
  750.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  751.     ASSERT_VALID(pThis);
  752.     return pThis->m_pOwner->m_xOleObject.EnumVerbs(ppenumOleVerb);
  753. }
  754.  
  755. STDMETHODIMP CDocObjectServer::XOleObject::Update()
  756. {
  757.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  758.     ASSERT_VALID(pThis);
  759.     return pThis->m_pOwner->m_xOleObject.Update();
  760. }
  761.  
  762. STDMETHODIMP CDocObjectServer::XOleObject::IsUpToDate()
  763. {
  764.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  765.     ASSERT_VALID(pThis);
  766.     return pThis->m_pOwner->m_xOleObject.IsUpToDate();
  767. }
  768.  
  769. STDMETHODIMP CDocObjectServer::XOleObject::GetUserClassID(CLSID* lpClassID)
  770. {
  771.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  772.     ASSERT_VALID(pThis);
  773.     return pThis->m_pOwner->m_xOleObject.GetUserClassID(lpClassID);
  774. }
  775.  
  776. STDMETHODIMP CDocObjectServer::XOleObject::GetUserType(
  777.     DWORD dwFormOfType, LPOLESTR* ppszUserType)
  778. {
  779.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  780.     ASSERT_VALID(pThis);
  781.     return pThis->m_pOwner->m_xOleObject.GetUserType(dwFormOfType, ppszUserType);
  782. }
  783.  
  784. STDMETHODIMP CDocObjectServer::XOleObject::SetExtent(
  785.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  786. {
  787.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  788.     ASSERT_VALID(pThis);
  789.  
  790.     // DocObjects ignore SetExtent calls, so returne E_FAIL
  791.     if (pThis->m_pOwner->IsDocObject())
  792.         return E_FAIL;
  793.  
  794.     // Otherwise, just do the normal processing
  795.     return pThis->m_pOwner->m_xOleObject.SetExtent(dwDrawAspect, lpsizel);
  796. }
  797.  
  798. STDMETHODIMP CDocObjectServer::XOleObject::GetExtent(
  799.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  800. {
  801.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  802.     ASSERT_VALID(pThis);
  803.     return pThis->m_pOwner->m_xOleObject.GetExtent(dwDrawAspect, lpsizel);
  804. }
  805.  
  806. STDMETHODIMP CDocObjectServer::XOleObject::Advise(
  807.     LPADVISESINK pAdvSink, DWORD* pdwConnection)
  808. {
  809.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  810.     ASSERT_VALID(pThis);
  811.     return pThis->m_pOwner->m_xOleObject.Advise(pAdvSink, pdwConnection);
  812. }
  813.  
  814. STDMETHODIMP CDocObjectServer::XOleObject::Unadvise(DWORD dwConnection)
  815. {
  816.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  817.     ASSERT_VALID(pThis);
  818.     return pThis->m_pOwner->m_xOleObject.Unadvise(dwConnection);
  819. }
  820.  
  821. STDMETHODIMP CDocObjectServer::XOleObject::EnumAdvise(
  822.     LPENUMSTATDATA* ppenumStatData)
  823. {
  824.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  825.     ASSERT_VALID(pThis);
  826.     return pThis->m_pOwner->m_xOleObject.EnumAdvise(ppenumStatData);
  827. }
  828.  
  829. STDMETHODIMP CDocObjectServer::XOleObject::GetMiscStatus(
  830.     DWORD dwAspect, DWORD* pdwStatus)
  831. {
  832.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  833.     ASSERT_VALID(pThis);
  834.     return pThis->m_pOwner->m_xOleObject.GetMiscStatus(dwAspect, pdwStatus);
  835. }
  836.  
  837. STDMETHODIMP CDocObjectServer::XOleObject::SetColorScheme(LPLOGPALETTE lpLogpal)
  838. {
  839.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  840.     ASSERT_VALID(pThis);
  841.     return pThis->m_pOwner->m_xOleObject.SetColorScheme(lpLogpal);
  842. }
  843.  
  844.  
  845. /////////////////////////////////////////////////////////////////////////////
  846. // CDocObjectServer diagnostics
  847.  
  848. #ifdef _DEBUG
  849. void CDocObjectServer::AssertValid() const
  850. {
  851.     ASSERT(m_pOwner != NULL);
  852.     CCmdTarget::AssertValid();
  853. }
  854.  
  855. void CDocObjectServer::Dump(CDumpContext& dc) const
  856. {
  857.     CCmdTarget::Dump(dc);
  858.     dc << "m_pDocSite = " << m_pDocSite << "\n";
  859.     dc << "m_pViewSite = " << m_pViewSite << "\n";
  860. }
  861. #endif //_DEBUG
  862.  
  863.  
  864. /////////////////////////////////////////////////////////////////////////////
  865. // CDocObjectServerItem implementation
  866.  
  867. IMPLEMENT_DYNAMIC(CDocObjectServerItem, COleServerItem)
  868.  
  869. CDocObjectServerItem::CDocObjectServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete)
  870.     : COleServerItem(pServerDoc, bAutoDelete)
  871. {
  872. }
  873.  
  874. CDocObjectServerItem::~CDocObjectServerItem()
  875. {
  876. }
  877.  
  878. void CDocObjectServerItem::OnDoVerb(LONG iVerb)
  879. {
  880.    COleServerDoc* pDoc = GetDocument();
  881.    ASSERT_VALID(pDoc);
  882.  
  883.    if (pDoc->IsDocObject() && (iVerb == OLEIVERB_INPLACEACTIVATE || iVerb == OLEIVERB_SHOW) )
  884.       OnShow();
  885.    else
  886.       COleServerItem::OnDoVerb(iVerb);
  887. }
  888.  
  889. void CDocObjectServerItem::OnHide()
  890. {
  891.    COleServerDoc* pDoc = GetDocument();
  892.    ASSERT_VALID(pDoc);
  893.  
  894.    if (pDoc->IsDocObject())
  895.       AfxThrowOleException(OLEOBJ_E_INVALIDVERB);
  896.    else
  897.       COleServerItem::OnHide();
  898. }
  899.  
  900. void CDocObjectServerItem::OnOpen()
  901. {
  902.    COleServerDoc* pDoc = GetDocument();
  903.    ASSERT_VALID(pDoc);
  904.  
  905.    if (pDoc->IsDocObject())
  906.       pDoc->ActivateDocObject();
  907.    else
  908.       COleServerItem::OnOpen();
  909. }
  910.  
  911. void CDocObjectServerItem::OnShow()
  912. {
  913.    COleServerDoc* pDoc = GetDocument();
  914.    ASSERT_VALID(pDoc);
  915.  
  916.    if (pDoc->IsDocObject())
  917.       pDoc->ActivateDocObject();
  918.    else
  919.       COleServerItem::OnShow();
  920. }
  921.  
  922. #ifdef _DEBUG
  923. void CDocObjectServerItem::AssertValid() const
  924. {
  925.     COleServerItem::AssertValid();
  926. }
  927.  
  928. void CDocObjectServerItem::Dump(CDumpContext& dc) const
  929. {
  930.     COleServerItem::Dump(dc);
  931. }
  932. #endif
  933.